﻿#include "CustomSimulation.h"
using namespace std;
using namespace ASL;

// 构造函数
SineModel::SineModel()
{
    // 模型基本信息
    this->setName("自定义正弦信号模型");
    this->setModelClass("SineModel");
    this->setDescription("用于输出自定义正弦信号");

    // 实例化端口对象 输出信号 -
    vY = new ASLData();
    vY->setName("Y");
    vY->setUnit("-");
    vY->setPortType(ASLData::PortType::Output);
    vY->setReal(0);
    this->setModelIO(vY);

    // 实例化端口对象 幅值 -
    vAmplitude = new ASLData();
    vAmplitude->setName("Amplitude");
    vAmplitude->setUnit("-");
    vAmplitude->setPortType(ASLData::PortType::Parameter);
    vAmplitude->setReal(1.0);
    this->setModelIO(vAmplitude);

    // 实例化端口对象 频率 Hz
    vFrequency = new ASLData();
    vFrequency->setName("Frequency");
    vFrequency->setUnit("Hz");
    vFrequency->setPortType(ASLData::PortType::Parameter);
    vFrequency->setReal(1.0);
    this->setModelIO(vFrequency);

    // 实例化端口对象 偏移 deg
    vOffset = new ASLData();
    vOffset->setName("Offset");
    vOffset->setUnit("deg");
    vOffset->setPortType(ASLData::PortType::Parameter);
    vOffset->setReal(0.0);
    this->setModelIO(vOffset);
}

// 析构函数
SineModel::~SineModel()
{
}

// 初始化函数
bool SineModel::initialize(ASLSimulator *simulator)
{
    // 获取模型参数端口数值
    amplitude = vAmplitude->toReal();
    frequency = vFrequency->toReal();
    offset = vOffset->toReal();

    this->step(simulator);

    return true;
}

// 单步运行函数
bool SineModel::step(ASLSimulator *simulator)
{
    double time, y;
    double pi = 3.1415926;

    // 获取仿真引擎当前周期时间指针
    time = simulator->currentTime();

    // 计算当前周期正弦信号输出值
    y = amplitude * sin(2 * pi * frequency * time + offset / 57.3);

    // 更新输出端口数值
    vY->setReal(y);

    return true;
}

// 构造函数
IntegrateModel::IntegrateModel()
{
    // 模型基本信息
    this->setName("自定义积分运算模型");
    this->setModelClass("IntegrateModel");
    this->setDescription("使用数值积分法计算积分值");

    // 实例化端口对象 输入信号 -
    vU = new ASLData();
    vU->setName("U");
    vU->setUnit("-");
    vU->setPortType(ASLData::PortType::Input);
    vU->setReal(0.0);
    this->setModelIO(vU);

    // 实例化端口对象 输出信号 -
    vY = new ASLData();
    vY->setName("Y");
    vY->setUnit("-");
    vY->setPortType(ASLData::PortType::Output);
    vY->setReal(0.0);
    this->setModelIO(vY);

    // 实例化端口对象 积分初值 -
    vInitialValue = new ASLData();
    vInitialValue->setName("InitialValue");
    vInitialValue->setUnit("-");
    vInitialValue->setPortType(ASLData::PortType::Parameter);
    vInitialValue->setReal(0.0);
    this->setModelIO(vInitialValue);
}

// 析构函数
IntegrateModel::~IntegrateModel()
{
}

// 初始化函数
bool IntegrateModel::initialize(ASLSimulator *simulator)
{
    // 获取模型参数端口数值
    initialValue = vInitialValue->toReal();

    // 初始化积分器配置（计算初值/仿真步长/求解器类型）
    cIntegrator.initialize(Calculus::ModeType::Integrate, initialValue, simulator->stepSize(), simulator->solver());

    // 使用积分初值初始化输出信号
    vY->setReal(initialValue);

    return true;
}

// 单步运行函数
bool IntegrateModel::step(ASLSimulator *simulator)
{
    double u, y;

    // 获取输入信号
    u = vU->toReal();

    // 积分器执行单步运算
    cIntegrator.step(u);

    // 获取当前周期积分计算结果
    y = cIntegrator.value(Calculus::ValueType::X, 0);

    // 更新输出信号
    vY->setReal(y);

    return true;
}

ClockModel::ClockModel()
{
    // 模型基本信息
    this->setName("自定义时钟模型");
    this->setModelClass("ClockModel");
    this->setDescription("用于输出当前周期仿真时间信号");

    // 实例化端口对象 仿真时间指针 s
    vT = new ASLData();
    vT->setName("Time");
    vT->setUnit("s");
    vT->setReal(0);
    vT->setPortType(ASLData::PortType::Output);
    this->setModelIO(vT);
}

ClockModel::~ClockModel()
{
}

// 初始化函数
bool ClockModel::initialize(ASLSimulator *simulator)
{
    this->step(simulator);

    return true;
}

// 单步运行函数
bool ClockModel::step(ASLSimulator *simulator)
{
    double time;

    // 获取仿真引擎当前周期时间指针
    time = simulator->currentTime();

    // 更新输出端口数值
    vT->setReal(time);

    return true;
}

// 构造函数
DerivateModel::DerivateModel()
{
    // 模型基本信息
    this->setName("自定义微分运算模型");
    this->setModelClass("DerivateModel");
    this->setDescription("使用数值微分法计算积分值");

    // 实例化端口对象 输入信号 -
    vU = new ASLData();
    vU->setName("U");
    vU->setUnit("-");
    vU->setPortType(ASLData::PortType::Input);
    vU->setReal(0.0);
    this->setModelIO(vU);

    // 实例化端口对象 输出信号 -
    vY = new ASLData();
    vY->setName("Y");
    vY->setUnit("-");
    vY->setPortType(ASLData::PortType::Output);
    vY->setReal(0.0);
    this->setModelIO(vY);

    // 实例化端口对象 微分初值 -
    vInitialValue = new ASLData();
    vInitialValue->setName("InitialValue");
    vInitialValue->setUnit("-");
    vInitialValue->setPortType(ASLData::PortType::Parameter);
    vInitialValue->setReal(0.0);
    this->setModelIO(vInitialValue);
}

// 析构函数
DerivateModel::~DerivateModel()
{
}

// 初始化函数
bool DerivateModel::initialize(ASLSimulator *simulator)
{
    // 获取模型参数端口数值
    initialValue = vInitialValue->toReal();

    // 初始化微分器配置
    cDerivator.initialize(Calculus::ModeType::Derivate, initialValue, simulator->stepSize(), simulator->solver());

    // 使用微分初值初始化输出信号
    vY->setReal(initialValue);

    return true;
}

// 单步运行函数
bool DerivateModel::step(ASLSimulator *simulator)
{
    double u, y;

    // 获取输入信号
    u = vU->toReal();

    // 微分器执行单步运算
    cDerivator.step(u);

    // 获取当前周期微分计算结果
    y = cDerivator.value(Calculus::ValueType::XDot, 0);

    // 更新输出信号
    vY->setReal(y);

    return true;
}